{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "71a329f0",
   "metadata": {},
   "source": [
    "# Speculative Decoding deployment guide for Neuron instances\n",
    "In this tutorial, you will use LMI container from DLC to SageMaker and run inference with it.\n",
    "\n",
    "Please make sure the following permission granted before running the notebook:\n",
    "\n",
    "- SageMaker access\n",
    "\n",
    "## Step 1: Let's bump up SageMaker and import stuff"
   ]
  },
  {
   "cell_type": "code",
   "id": "67fa3208",
   "metadata": {},
   "source": [
    "%pip install sagemaker boto3 awscli --upgrade  --quiet"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "ec9ac353",
   "metadata": {},
   "source": [
    "import sagemaker\n",
    "from sagemaker.djl_inference.model import DJLModel\n",
    "\n",
    "role = sagemaker.get_execution_role()  # execution role for the endpoint\n",
    "session = sagemaker.session.Session()  # sagemaker session for interacting with different AWS APIs"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "2e58cf33",
   "metadata": {},
   "source": [
    "## Step 2: Start building SageMaker endpoint\n",
    "In this step, we will build SageMaker endpoint from scratch"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d955679",
   "metadata": {},
   "source": [
    "### Getting the container image URI (optional)\n",
    "\n",
    "Check out available images: [Large Model Inference available DLC](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#large-model-inference-containers)"
   ]
  },
  {
   "cell_type": "code",
   "id": "7a174b36",
   "metadata": {},
   "source": [
    "# Choose a specific version of LMI image directly:\n",
    "image_uri = \"763104351884.dkr.ecr.us-west-2.amazonaws.com/djl-inference:0.28.0-neuronx-sdk2.18.2\""
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "11601839",
   "metadata": {},
   "source": [
    "### Create SageMaker model\n",
    "\n",
    "Here we are using [LMI PySDK](https://sagemaker.readthedocs.io/en/stable/frameworks/djl/using_djl.html) to create the model.\n",
    "\n",
    "Checkout more [configuration options](https://docs.djl.ai/docs/serving/serving/docs/lmi/deployment_guide/configurations.html#environment-variable-configurations)."
   ]
  },
  {
   "cell_type": "code",
   "id": "38b1e5ca",
   "metadata": {},
   "source": [
    "# model_id = \"s3://YOUR_BUCKET\"                 # download model from your s3 bucket\n",
    "model_id = \"TheBloke/Llama-2-70B-Chat-fp16\"     # model will be download form Huggingface hub\n",
    "draft_model_id = \"TinyLlama/TinyLlama-1.1B-Chat-v1.0\"\n",
    "env = {\n",
    "    \"TENSOR_PARALLEL_DEGREE\": \"24\",           \n",
    "    \"OPTION_ROLLING_BATCH\": \"auto\",           \n",
    "    \"OPTION_MODEL_LOADING_TIMEOUT\": \"3600\",   \n",
    "    \"OPTION_SPECULATIVE_DRAFT_MODEL\": draft_model_id,\n",
    "    \"OPTION_N_POSITIONS\": \"1024\",\n",
    "    \"OPTION_ROLLING_BATCH_SIZE\": \"1\",\n",
    "    \"OPTION_ENTRYPOINT\": \"djl_python.transformers_neuronx\",\n",
    "}\n",
    "\n",
    "model = DJLModel(\n",
    "    model_id=model_id,\n",
    "    image_uri=image_uri, # choose a specific version of LMI DLC image\n",
    "    env=env,\n",
    "    role=role)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "004f39f6",
   "metadata": {},
   "source": [
    "### Create SageMaker endpoint\n",
    "\n",
    "You need to specify the instance to use and endpoint names"
   ]
  },
  {
   "cell_type": "code",
   "id": "8e0e61cd",
   "metadata": {
    "jupyter": {
     "is_executing": true
    }
   },
   "source": [
    "instance_type = \"ml.inf2.48xlarge\"\n",
    "endpoint_name = sagemaker.utils.name_from_base(\"lmi-model\")\n",
    "\n",
    "predictor = model.deploy(initial_instance_count=1,\n",
    "             instance_type=instance_type,\n",
    "             endpoint_name=endpoint_name,\n",
    "             container_startup_health_check_timeout=3600,\n",
    "             volume_size=512\n",
    "            )"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "bb63ee65",
   "metadata": {},
   "source": [
    "## Step 3: Test and benchmark the inference"
   ]
  },
  {
   "cell_type": "code",
   "id": "2bcef095",
   "metadata": {},
   "source": [
    "%%timeit -n3 -r1\n",
    "predictor.predict(\n",
    "    {\"inputs\": \"Large model inference is\", \"parameters\": {}}\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "c1cd9042",
   "metadata": {},
   "source": [
    "## Clean up the environment"
   ]
  },
  {
   "cell_type": "code",
   "id": "3d674b41",
   "metadata": {},
   "source": [
    "session.delete_endpoint(endpoint_name)\n",
    "session.delete_endpoint_config(endpoint_name)\n",
    "model.delete_model()"
   ],
   "outputs": [],
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
